#include"Log.hpp"
#include<sys/epoll.h>
#include <errno.h>      // For errno
#include <cassert>      // For assert
#include <vector>       // For std::vector
#include <unordered_map> // For std::unordered_map
#include <cstring>      // For strerror
// #include <Channel.hpp>

#define MAX_EPOLLEVENTS 1024
class Poller{
private:
    int _epfd;//用一个文件描述符_epfd管理文件,
    struct epoll_event _evs[MAX_EPOLLEVENTS]; //事件队列
    std::unordered_map<int,Channel *> _channels;
private:
    //对epoll的直接操作
    void Update(Channel *channel ,int op){
        int fd = channel->Fd();
        struct epoll_event ev;
        ev.data.fd = fd;
        ev.events = channel->Events();
        int ret = epoll_ctl(_epfd,op,fd,&ev); 
        if(ret<0){
            lg(Error,"EPOLLCTL FAILED!");
        }   
        return;
    }
    //判断Channel是否添加了事件监控
    bool HashChannel(Channel *channel){
        auto it = _channel.find(channel->Fd());
        if(it == _channel.end()){
            return false;
        }
        return true;
    }
public:
    Poller(){
        _epfd = epoll_create(MAX_EPOLLEVENTS);//系统调用创建epoll
        if(_epfd < 0){
            lg(Error,"EPOLL CREATE FAILED!!");
            abort(); //创建失败，退出
        }
    }
    //添加或修改监控事件
    void UpdataEvent(Channel *channel){
        bool ret = HashChannel(channel);
        if(ret == false){
            _channel.insert(std::make_pair(channel->Fd(),channel));
            return Update(channel,EPOLL_CTL_ADD);
        }
        return Update(channel,EPOLL_CTL_MOD);
    }
    //移除监控
    void RemoveEvent(Channel *channel){
        auto it = _channels.find(channel.Fd());
        if(it != _channels.end()){
            _channel.erase(it);
        }
        Update(channel,EPOLL_CTL_DEL);
    }
    //开始监控。
    void Poll(std::vector<Channel*> active){
        int nfds = epoll_wait(_epfd,_evs,MAX_EPOLLEVENTS,-1);
        if(nfds < 0){
            if(errno == EINTR){ //EINTR：进程在
                //慢系统调用中阻塞，捕获到某个信号且相应的信号处理函
                //
                return;
            }
            lg(Error,"EPOLL WAIT ERROR:%s\n",strerror(errno));
            abort();
        }
        for(int i=0;i < nfds;i++){//f
            auto it = _channels.find(_evs[i].data.fd);
            assert(it !=  _channels.end());
            it ->second ->SetREvents(_evs[i].events);//设置实际就绪的事件
            active->push_back(it->second);
        }
        return;
    }    
}

int main(){
    return 0;
}
